package org.opens.guava.utilites.eventBus.events;

import com.google.common.eventbus.EventBus;
import org.junit.Test;
import org.opens.guava.utilites.eventBus.base.Apple;
import org.opens.guava.utilites.eventBus.listeners.EatFruitListener;
import org.opens.guava.utilites.eventBus.listeners.ExceptionListener;
import org.opens.guava.utilites.eventBus.listeners.SimpleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExceptionEventBusExample {

    private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionEventBusExample.class);

    /**
     * 功能:
     *      测试发生异常时, eventBus是怎么处理的.
     * 输出:
     *      13:10:47.660 [main] INFO org.opens.guava.utilites.eventBus.listeners.SimpleListener - the event: [s1] handle by ExceptionListener.doAction3
     *
     *      十一月 09, 2019 1:10:47 下午 com.google.common.eventbus.EventBus$LoggingHandler handleException
     *      13:10:47.660 [main] INFO org.opens.guava.utilites.eventBus.listeners.SimpleListener - the event: [s1] handle by ExceptionListener.doAction1
     *      严重: Exception thrown by subscriber method doAction3(java.lang.String) on subscriber org.opens.guava.utilites.eventBus.listeners.ExceptionListener@6ebc05a6 when dispatching event: s1
     *      13:10:47.660 [main] INFO org.opens.guava.utilites.eventBus.listeners.SimpleListener - the event: [s1] handle by ExceptionListener.doAction2
     *      java.lang.RuntimeException: 假设发生了异常
     * 说明:
     *      1. 可以发现, 三个事件方法都成功的执行了, 但是也有异常信息, 这就说明了:
     *          - 单个事件方法的异常不会影响其他事件(底层使用了try...catch...), 但是发生异常的时间方法会被中断且打印异常信息.
     */
    @Test
    public void test1() {
        final EventBus eventBus = new EventBus();
        eventBus.register(new ExceptionListener());
        eventBus.post("s1");
    }

    /**
     * 功能:
     *      给EventBus传入一个异常处理器, 使事件方法抛出异常时执行特定的逻辑.
     * 输出:
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.listeners.ExceptionListener - the event: [s1] handle by ExceptionListener.doAction3
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.events.ExceptionEventBusExample - s1
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.events.ExceptionEventBusExample - EventBus{default}
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.events.ExceptionEventBusExample - org.opens.guava.utilites.eventBus.listeners.ExceptionListener@30a3107a
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.events.ExceptionEventBusExample - public void org.opens.guava.utilites.eventBus.listeners.ExceptionListener.doAction3(java.lang.String)
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.listeners.ExceptionListener - the event: [s1] handle by ExceptionListener.doAction2
     *      13:23:49.404 [main] INFO org.opens.guava.utilites.eventBus.listeners.ExceptionListener - the event: [s1] handle by ExceptionListener.doAction1
     * 说明:
     *      1. getEvent()获取的是事件参数;
     *      2. getEventBus()获取的是事件总线的名称;
     *      3. getSubscriber()获取的是时间方法的类;
     *      4. getSubscriberMethod()获取的是时间方法的反射类型.
     * 注意:
     *      1. 此处使用了java8的语法, 还可以使用自定义类实现SubscriberExceptionHandler接口, 并重写handleException方法.
     */
    @Test
    public void test2() {
        final EventBus eventBus = new EventBus((exception, context) -> {
            LOGGER.info(context.getEvent().toString());
            LOGGER.info(context.getEventBus().toString());
            LOGGER.info(context.getSubscriber().toString());
            LOGGER.info(context.getSubscriberMethod().toString());
        });
        eventBus.register(new ExceptionListener());
        eventBus.post("s1");
    }

}
